package com.card.hwatt.controllers;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.card.hwatt.assembler.CardAssembler;
import com.card.hwatt.assembler.CardRecordAssembler;
import com.card.hwatt.assembler.EmployeeAssembler;
import com.card.hwatt.assembler.HolidayAssembler;
import com.card.hwatt.assembler.LeaveAssembler;
import com.card.hwatt.assembler.MonthWorkAssembler;
import com.card.hwatt.assembler.PrivateWorkSumAssembler;
import com.card.hwatt.assembler.ScheduleAssembler;
import com.card.hwatt.dto.*;
import com.card.hwatt.service.CardService;
import com.card.hwatt.service.EmployeeService;
import com.card.hwatt.service.HolidayService;
import com.card.hwatt.service.LeaveService;
import com.card.hwatt.service.ScheduleService;

/**
 * 个人考勤
 * 
 * @author Administrator
 * 
 */
@Controller
@Scope("prototype")
@RequestMapping("/private")
public class PrivateController extends BaseController {

	@Autowired
	@Qualifier("employeeService")
	private EmployeeService employeeService;

	@Autowired
	@Qualifier("cardService")
	private CardService cardService;

	@Autowired
	@Qualifier("scheduleService")
	private ScheduleService scheduleService;

	@Autowired
	@Qualifier("holidayService")
	private HolidayService holidayService;

	@Autowired
	@Qualifier("leaveService")
	private LeaveService leaveService;

	@RequestMapping("/schedule")
	public String schedule(HttpServletRequest request, ModelMap modelMap) {
		HttpSession session = request.getSession();
		modelMap.put("code", session.getAttribute("employeeCode"));
		modelMap.put("user", session.getAttribute("user"));
		modelMap.put("departmentId", session.getAttribute("departmentId"));
		return "privateschedule";
	}

	/**
	 * 个人考勤汇总
	 * 
	 * @return
	 */
	@RequestMapping("/worksum")
	public String workSum(HttpServletRequest request, ModelMap modelMap) {
		HttpSession session = request.getSession();
		modelMap.put("code", session.getAttribute("employeeCode"));
		modelMap.put("user", session.getAttribute("user"));
		modelMap.put("departmentId", session.getAttribute("departmentId"));
		return "privateworksum";
	}

	private Employee getEmployeeByCode(String code) {
		List<Object> params = new ArrayList<Object>();
		params.add(code);

		List<Employee> result = EmployeeAssembler.convert(employeeService
				.loadAll(new PageParam(0, 0, " employeeCode = ? ", params,
						" employeeCode asc ")).rows);

		if (result.size() == 0) {
			return null;
		}
		return result.get(0);
	}

	private List<Card> loadCard(String code, Integer year, Integer month) {

		if (year == null || month == null) {
			return new ArrayList<Card>();
		}

		String[] parsePatterns = new String[] { "yyyy-M-dd HH:mm:ss" };
		Date startDate = null;
		try {
			startDate = DateUtils.parseDate(
					String.format("%d-%d-01 00:00:00", year.intValue(),
							month.intValue()), parsePatterns);
		} catch (Exception e) {
			startDate = new Date();
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(startDate);
		calendar.add(Calendar.MONTH, 1);
		calendar.add(Calendar.DATE, 1);
		Date endDate = calendar.getTime();

		List<Object> params = new ArrayList<Object>();
		params.add(new java.sql.Date(startDate.getTime()));
		params.add(new java.sql.Date(endDate.getTime()));

		params.add(code);

		String hql = " date >= ? and date < ?  and employee.employeeCode = ? ) ";
		List<Card> result = CardAssembler.convert(cardService
				.loadAll(new PageParam(0, 0, hql, params, " date asc ")).rows);

		return result;
	}

	private List<Leave> loadLeave(String code, Integer year, Integer month) {
		if (year == null || month == null) {
			return new ArrayList<Leave>();
		}

		String[] parsePatterns = new String[] { "yyyy-M-dd" };
		Date startDate = null;
		try {
			startDate = DateUtils.parseDate(String.format("%d-%d-01",
					year.intValue(), month.intValue()), parsePatterns);
		} catch (Exception e) {
			startDate = new Date();
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(startDate);
		calendar.add(Calendar.MONTH, 1);

		Date endDate = calendar.getTime();

		List<Object> params = new ArrayList<Object>();

		String pattern = "yyyyMMdd";
		params.add(DateFormatUtils.format(startDate, pattern));
		params.add(DateFormatUtils.format(endDate, pattern));
		params.add(code);

		String hql = " name >= ? and name < ? and  employee.employeeCode = ? ";
		List<Leave> result = LeaveAssembler.convert(leaveService
				.loadAll(new PageParam(0, 0, hql, params, " name desc ")).rows);
		return result;
	}

	private List<Holiday> loadHoliday(Integer year, Integer month) {
		if (year == null || month == null) {
			return new ArrayList<Holiday>();
		}

		String[] parsePatterns = new String[] { "yyyy-M-dd" };
		Date startDate = null;
		try {
			startDate = DateUtils.parseDate(String.format("%d-%d-01",
					year.intValue(), month.intValue()), parsePatterns);
		} catch (Exception e) {
			startDate = new Date();
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(startDate);
		calendar.add(Calendar.MONTH, 1);

		Date endDate = calendar.getTime();

		List<Object> params = new ArrayList<Object>();

		String pattern = "yyyyMMdd";
		params.add(DateFormatUtils.format(startDate, pattern));
		params.add(DateFormatUtils.format(endDate, pattern));

		List<Holiday> result = HolidayAssembler.convert(holidayService
				.loadAll(new PageParam(0, 0, " id >= ? and id < ? ", params,
						" id desc ")).rows);
		return result;
	}

	private Map<String, Object> getDefualtPrivateWorkSum() {
		Map<String, Object> result = new HashMap<String, Object>();
		List<PrivateWorkSum> rows = new ArrayList<PrivateWorkSum>();
		for (int i = 1; i <= 12; i++) {
			PrivateWorkSum privateWorkSum = new PrivateWorkSum();
			privateWorkSum.month = i + "月";
			rows.add(privateWorkSum);
		}
		result.put("total", rows.size());
		result.put("rows", rows);
		PrivateWorkSum footer = new PrivateWorkSum();
		footer.month = "汇总";
		result.put("footer", new PrivateWorkSum[] { footer });
		return result;
	}

	@RequestMapping("/loadAllWorkSum")
	public @ResponseBody
	Map<String, Object> loadAllWorkSum(Integer year, String code) {
		if (year == null || StringUtils.isEmpty(code)) {
			return getDefualtPrivateWorkSum();
		}

		Employee employee = getEmployeeByCode(code);
		if (employee == null) {
			return getDefualtPrivateWorkSum();
		}

		Schedule schedule = ScheduleAssembler.convert(scheduleService.get(year
				+ "-01-01", employee.departmentId));
		if (schedule == null) {
			return getDefualtPrivateWorkSum();
		}

		List<MonthWork> rows = new ArrayList<MonthWork>();
		for (int i = 1; i <= 12; i++) {
			MonthWork monthWork = getMonthSum(employee, schedule, year, i, code);
			rows.add(monthWork == null ? new MonthWork() : monthWork);
		}

		Map<String, Object> result = PrivateWorkSumAssembler.convert(rows);
		return result;
	}

	private MonthWork getMonthSum(Employee employee, Schedule schedule,
			Integer year, Integer month, String code) {

		List<Card> cards = loadCard(code, year, month);
		List<Leave> leaves = loadLeave(code, year, month);

		List<Holiday> holidaies = loadHoliday(year, month);

		Calendar end = Calendar.getInstance();
		end.set(year, month - 1, 1, 0, 0, 0);
		end.add(Calendar.MONTH, 1);

		List<Employee> employees = new ArrayList<Employee>();
		employees.add(employee);

		List<CardRecord> list = CardRecordAssembler.convert(employees, cards,
				schedule, DateFormatUtils.format(end, "yyyy-MM-dd"));

		Map<String, Object> map = MonthWorkAssembler.convert(employees, list,
				leaves, holidaies, schedule);
		@SuppressWarnings("unchecked")
		List<MonthWork> result = (List<MonthWork>) map.get("rows");
		return CollectionUtils.isEmpty(result) ? null : result.get(0);

	}

	/**
	 * 个人刷脸记录
	 * 
	 * @return
	 */
	@RequestMapping("/card")
	public String card(HttpServletRequest request, ModelMap modelMap) {
		HttpSession session = request.getSession();
		modelMap.put("code", session.getAttribute("employeeCode"));
		modelMap.put("user", session.getAttribute("user"));
		modelMap.put("departmentId", session.getAttribute("departmentId"));
		return "privatecard";
	}

	/**
	 * 个人刷脸记录统计
	 * 
	 * @return
	 */
	@RequestMapping("/cardrecord")
	public String cardrecord(HttpServletRequest request, ModelMap modelMap) {
		HttpSession session = request.getSession();
		modelMap.put("code", session.getAttribute("employeeCode"));
		modelMap.put("user", session.getAttribute("user"));
		modelMap.put("departmentId", session.getAttribute("departmentId"));
		return "privatecardrecord";
	}

	/**
	 * 个人请假查询
	 * 
	 * @return
	 */
	@RequestMapping("/leave")
	public String leave(HttpServletRequest request, ModelMap modelMap) {
		HttpSession session = request.getSession();
		modelMap.put("code", session.getAttribute("employeeCode"));
		modelMap.put("user", session.getAttribute("user"));
		modelMap.put("departmentId", session.getAttribute("departmentId"));
		return "privateleave";
	}

	/**
	 * 个人特殊考勤查询
	 * 
	 * @return
	 */
	@RequestMapping("/special")
	public String special(HttpServletRequest request, ModelMap modelMap) {
		HttpSession session = request.getSession();
		modelMap.put("code", session.getAttribute("employeeCode"));
		modelMap.put("user", session.getAttribute("user"));
		modelMap.put("departmentId", session.getAttribute("departmentId"));
		return "privatespecial";
	}
}
